#include <iostream>
#include <cstring>
#include <cerrno>
#include "commen.hpp"

// IPC_CREAT 无则新建，有则获取 -> 用于获取共享内存
// IPC_EXCL | IPC_CREAT 无则新建，有则出错返回 -> 用于创建全新的共享内存

// key不在应用层代码中使用，只用来在内核中标识共享内存的唯一性，代码和指令中使用shmid管理共享内存

class AutoShm
{
public:
    AutoShm()
    {
        // 生成key
        key_t key = getKey();
        std::cout << "key: " << toHex(key) << std::endl;

        // 获取共享内存
        shmid = createShm(key);
        std::cout << "shmid: " << shmid << std::endl;

        // 关联共享内存
        content = (char *)shmat(shmid, nullptr, 0);
        std::cout << "关联共享内存" << std::endl;
    }

    ~AutoShm()
    {
        // 去关联共享内存
        shmdt(content);
        std::cout << "去关联共享内存" << std::endl;

        // 删除共享内存
        shmctl(shmid, IPC_RMID, nullptr);
        std::cout << "删除共享内存" << std::endl;
    }
public:
    int shmid;
    char* content;
};

class AutoSem
{
public:
    AutoSem()
    {
        key_t key = getKey();
        semid = semget(key, 1, IPC_CREAT | IPC_EXCL);
    }

    ~AutoSem()
    {
        semctl(semid, 0, IPC_RMID);
    }
public:
    int semid;
    char* content;
};

class AutoFifo
{
public:
    AutoFifo()
    {
        //借助管道，建立同步机制
        bool ret = makeFifo();
        if (ret == false) return;

        //打开读端
        fd = open(filename.c_str(), O_RDONLY);
    }

    ~AutoFifo()
    {
        //释放fd，删管道
        close(fd);
        unlink(filename.c_str());
    }
public:
    int fd;
};

int main()
{
    AutoShm autoShm;
    AutoFifo autoFifo;

    // 开始进程间通信
    while (true)
    {
        int code = 0;
        ssize_t n = read(autoFifo.fd, &code, sizeof(code));
        if (n > 0)
        {
            std::cout << "shm content: " << autoShm.content << std::endl;
            sleep(1);
        }
        else if (n == 0) //对端关闭
        {
            break;
        }
    }

    return 0;
}